import OpenGL.GL as gl
import numpy as np
from PIL import Image
import glm

class ImageTexture2D:
    def __init__(self, file_path: str) -> None:
        tex = np.empty(1, gl.GLuint)
        gl.glCreateTextures(gl.GL_TEXTURE_2D, 1, tex)
        self.tex_id = tex[0]
        image = Image.open(file_path).transpose(Image.FLIP_TOP_BOTTOM)
        self.width, self.height = image.size
        channels = len(image.getbands())
        if channels == 1:
            self.pixel_format = gl.GL_RED
            self.internal_format = gl.GL_R8
        elif channels == 2:
            self.pixel_format = gl.GL_RG
            self.internal_format = gl.GL_RG8
        elif channels == 3:
            self.pixel_format = gl.GL_RGB
            self.internal_format = gl.GL_RGB8
        elif channels == 4:
            self.pixel_format = gl.GL_RGBA
            self.internal_format = gl.GL_RGBA8
        gl.glTextureStorage2D(self.tex_id, 1, self.internal_format, 
                              self.width, self.height) 
        gl.glTextureSubImage2D(self.tex_id, 0, 0, 0, self.width, self.height,
                self.pixel_format, gl.GL_UNSIGNED_BYTE, image.tobytes())
        gl.glGenerateTextureMipmap(self.tex_id)

    def bind(self, index: int) -> None:
        gl.glBindTextureUnit(index, self.tex_id)

    def delete(self) -> None:
        if gl.glIsTexture(self.tex_id):
            gl.glDeleteTextures(1, self.tex_id)

    def setFiltering(self, min_filter: int, mag_filter: int) -> None:
        gl.glTextureParameteri(self.tex_id, gl.GL_TEXTURE_MIN_FILTER, min_filter)
        gl.glTextureParameteri(self.tex_id, gl.GL_TEXTURE_MAG_FILTER, mag_filter)

    def setWrapMode(self, wrap_s: int, wrap_t: int) -> None:
        gl.glTextureParameteri(self.tex_id, gl.GL_TEXTURE_WRAP_S, wrap_s)
        gl.glTextureParameteri(self.tex_id, gl.GL_TEXTURE_WRAP_T, wrap_t)

    def setBorderColor(self, color:glm.vec4) -> None:
        gl.glTextureParameterfv(self.tex_id, gl.GL_TEXTURE_BORDER_COLOR, 
                                color.to_tuple())

